package org.jtb.quickr;

import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.apache.log4j.Logger;
import org.jdom.Element;

/**
 * Photos response.
 *
 * @see org.jtb.quickr.PeopleService#getPublicPhotos(String)
 */
public class PhotosResponse extends FlickrResponse {
    private static Logger logger = Logger.getLogger(PhotosResponse.class.getName());
    private static final int SHORT_TITLE_LENGTH = 7;
    private static final String ELLIPSIS = "...";
    
    /**
     * Photos photo response.
     */
    public static class Photo extends FlickrResponse {
        private String photoId;
        private String owner;
        private String photoSecret;
        private String server;
        private String title;
        private String shortTitle;
        private String tags;
        private boolean publicAccessible;
        private boolean friendAccessible;
        private boolean familyAccessible;
        
        private String staticUrl;
        
        Photo(Element e, String staticUrl) throws QuickrException {
            super(e);
            this.staticUrl = staticUrl;
        }
        
        protected void populate(Element e) {
            this.publicAccessible = getAttrBoolean(e, "ispublic");
            this.friendAccessible = getAttrBoolean(e, "isfriend");
            this.familyAccessible = getAttrBoolean(e, "isfamily");
            
            this.photoId = e.getAttributeValue("id");
            this.owner = e.getAttributeValue("owner");
            this.photoSecret = e.getAttributeValue("secret");
            this.server = e.getAttributeValue("server");
            this.title = e.getAttributeValue("title");
            this.tags = e.getAttributeValue("tags");
            
            if (title.length() > SHORT_TITLE_LENGTH+ELLIPSIS.length()) {
                this.shortTitle = title.substring(0, SHORT_TITLE_LENGTH) + ELLIPSIS;
            } else {
                this.shortTitle = title;
            }
        }
        
        /**
         * Get scaled photo URL.
         * @param size Photo size.
         * @throws QuickrException If a problem occurs.
         * @return The photo URL.
         */
        public URL getUrl(PhotoSize size) throws QuickrException {
            PhotoUrl purl = new PhotoUrl(getStaticUrl(), getServer(), getPhotoId(), getPhotoSecret(), size);
            return purl.getUrl();
        }

        /**
         * Get thumbnail photo URL.
         * This is equivalend to <code>getUrl(PhotoSize.THUMBNAIL)</code>
         * @throws QuickrException If a problem occurs.
         * @return The photo URL.
         * @see #getUrl(PhotoSize)
         */
        public URL getThumbnailUrl() throws QuickrException {
            return getUrl(PhotoSize.THUMBNAIL);
        }

        /**
         * Get small square photo URL.
         * This is equivalend to <code>getUrl(PhotoSize.SMALL_SQUARE)</code>
         * @throws QuickrException If a problem occurs.
         * @return The photo URL.
         * @see #getUrl(PhotoSize)
         */
        public URL getSmallSquareUrl() throws QuickrException {
            return getUrl(PhotoSize.SMALL_SQUARE);
        }

        /**
         * Get small photo URL.
         * This is equivalend to <code>getUrl(PhotoSize.SMALL)</code>
         * @throws QuickrException If a problem occurs.
         * @return The photo URL.
         * @see #getUrl(PhotoSize)
         */
        public URL getSmallUrl() throws QuickrException {
            return getUrl(PhotoSize.SMALL);
        }
        
        /**
         * Get medium photo URL.
         * This is equivalend to <code>getUrl(PhotoSize.MEDIUM)</code>
         * @throws QuickrException If a problem occurs.
         * @return The photo URL.
         * @see #getUrl(PhotoSize)
         */
        public URL getMediumUrl() throws QuickrException {
            return getUrl(PhotoSize.MEDIUM);
        }

        /**
         * Get large photo URL.
         * This is equivalend to <code>getUrl(PhotoSize.LARGE)</code>
         * @throws QuickrException If a problem occurs.
         * @return The photo URL.
         * @see #getUrl(PhotoSize)
         */
        public URL getLargeUrl() throws QuickrException {
            return getUrl(PhotoSize.LARGE);
        }
        
        /**
         * Get original photo URL.
         * @param ext Photo extension.
         * @throws QuickrException If a problem occurs.
         * @return The photo URL.
         */
        public URL getOriginalUrl(String ext) throws QuickrException {
            PhotoUrl purl = new PhotoUrl(getStaticUrl(), getServer(), getPhotoId(), getPhotoSecret(), ext);
            return purl.getUrl();
        }
        
        /**
         * Get the string representation of this object.
         * @return This object as a string.
         */
        public String toString() {
            return this.getClass().getName() + " { photoId=" + getPhotoId() + ", server=" + getServer() + ", owner=" + getOwner() + ", secret=" + getPhotoSecret() + ", title=" + getTitle() + " }";
        }

        public String getPhotoId() {
            return photoId;
        }

        public String getOwner() {
            return owner;
        }

        public String getPhotoSecret() {
            return photoSecret;
        }

        public String getServer() {
            return server;
        }

        public String getShortTitle() {
            return shortTitle;
        }

        public String getTitle() {
            return title;
        }
        
        public String getTags() {
            return tags;
        }

        public boolean isPublicAccessible() {
            return publicAccessible;
        }

        public boolean isFriendAccessible() {
            return friendAccessible;
        }

        public boolean isFamilyAccessible() {
            return familyAccessible;
        }

        public String getStaticUrl() {
            return staticUrl;
        }
    }
    
    private int page;
    private int pages;
    private int perPage;
    private int total;
    private List<Photo> photos;
    private String staticUrl;
    
    PhotosResponse(InputStream is, String staticUrl) throws QuickrException {
        this.staticUrl = staticUrl;
        init(is);
    }
    
    protected void populate(Element e) throws QuickrException {
        Element photosElement = e.getChild("photos");
        
        this.page = getAttrInt(photosElement, "page");
        this.pages = getAttrInt(photosElement, "pages");
        this.perPage = getAttrInt(photosElement, "perpage");
        this.total = getAttrInt(photosElement, "total");
        
        photos = new ArrayList<Photo>();
        List photoElements = photosElement.getChildren("photo");
        if (logger.isDebugEnabled()) {
            logger.debug("number of photos: " + photoElements.size());
        }
        for (Iterator i = photoElements.iterator(); i.hasNext(); ) {
            Element photoElement = (Element)i.next();
            Photo p = new Photo(photoElement, staticUrl);
            photos.add(p);
        }
    }
    
    /**
     * Get photos.
     * @return The list of photo objects.
     */
    public List<Photo> getPhotos() {
        return photos;
    }
    
    private void setPhotos(List<Photo> photos) {
        this.photos = photos;
    }

    /**
     * Get the page number for this response.
     * @return The page number.
     */
    public int getPage() {
        return page;
    }

    /**
     * Get the total number of pages.
     * @return The total number of pages..
     */
    public int getPages() {
        return pages;
    }

    /**
     * Get the number of photos per page for this response.
     * @return The number of photos per page.
     */
    public int getPerPage() {
        return perPage;
    }

    /**
     * Get the total number of photos.
     * @return The total number of photos.
     */    
    public int getTotal() {
        return total;
    }
}
